using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Globalization;
using System.IO;
using System.Reflection;
using System.Text;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.Util;
using System.Xml;

using Behemoth.Reflection;

using Microsoft.SharePoint;
using Microsoft.Office.Server;
using Microsoft.Office.Server.Search.WebControls;
using Microsoft.Office.Server.Search.Query;

namespace Behemoth.SharePoint.WebParts {

    /// <summary>
    /// Matches the internal enum from srho.
    /// </summary>
    public enum ErrorLevel {
        Fatal = 0,
        Info = 2,
        NoError = 0x63,
        Warning = 1
    }

    /// <summary>
    /// This class provides access to members of srho that are hidden by 
    /// internal or private in the c# code. This is a well defined hack of IL
    /// and the .NET framework, abstracted here to make it more supportable.
    /// </summary>
    /// <remarks>
    /// The attempt to reference the object through reflection will be made 
    /// when you first try to access one of the public properties.
    /// </remarks>
    public class SearchResultHiddenObjectAccessor {

#warning SearchResultHiddenObjectAccessor class makes extensive use of reflection and should be used with great care and at your own risk.

        private CoreResultsWebPart _wp;
        public SearchResultHiddenObjectAccessor(CoreResultsWebPart wp) {
            if (wp == null)
                throw new NullReferenceException("You must provide a valid instance of CoreResultsWebPart or a class that inherits from it.");
            _wp = wp;
        }

        /// <summary>
        /// Set this property if you want to override the 'Write' fieldName when query results
        /// are sorted by 'Modified Date' instead of 'Relevance'. Provide the name
        /// of your managed property to be used in ORDER BY for Sql Query syntax.
        /// </summary>
        public string OverrideSqlWriteFieldName {
            get { return _overrideSqlWriteFieldName; }
            set { _overrideSqlWriteFieldName = value; }
        }
        private string _overrideSqlWriteFieldName = string.Empty;

        public string KeywordQuery {
            get {
                return this._srhoKeywordQuery;
            }
            set {
                this._srhoKeywordQuery = value;
                // eliminate any existing full text query
                if (!string.IsNullOrEmpty(value))
                    this._srhoFullTextQuery = string.Empty;
            }
        }

        public string FullTextQuery {
            get {
                return this._srhoFullTextQuery;
            }
            set {
                this._srhoFullTextQuery = value;
                // eliminate any existing keyword query
                if (!string.IsNullOrEmpty(value))
                    this._srhoKeywordQuery = string.Empty;
            }
        }

        /// <summary>
        /// Note that once you read this property, it will not be retreived
        /// again, but since it is an object reference, this shouldn't matter.
        /// </summary>
        public StringCollection SearchRequestProperties {
            get {
                if (_searchRequestProperties == null)
                    _searchRequestProperties = _srhoSearchRequestProperties;
                return _searchRequestProperties;
            }
        }
        private StringCollection _searchRequestProperties;

        protected object SRHO {
            get {
                EnsureSRHO();
                return _srho;
            }
        }
        private object _srho;

        /// <summary>
        /// Provides various ways of getting core results through reflection.
        /// Warning: this is the method actually calls the search web service.
        /// </summary>
        /// <returns></returns>
        public XmlDocument CoreResults {
            get {
                return get_CoreResults((!string.IsNullOrEmpty(OverrideSqlWriteFieldName)));
            }
        }

        #region Basic Reflective Property Access

        public string Scope {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "Scope", true);
                return o as string;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "Scope", true, value);
            }
        }

        protected StringCollection _srhoSearchRequestProperties {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "SearchRequestProperties", true);
                return o as StringCollection;
            }
        }

        protected XmlDocument m_xmlResponseDoc {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_xmlResponseDoc", false);
                return o as XmlDocument;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_xmlResponseDoc", false, value);
            }
        }

        protected XmlDocument m_xmlHighConfDoc {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_xmlHighConfDoc", false);
                return o as XmlDocument;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_xmlHighConfDoc", false, value);
            }
        }

        protected bool m_fDoneQuery {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_fDoneQuery", false);
                return (o == null) ? false : (bool)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_fDoneQuery", false, value);
            }
        }

        protected int m_iStartAt {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_iStartAt", false);
                return (o == null) ? 0 : (int)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_iStartAt", false, value);
            }
        }

        protected Int16 _HighestResultsPage {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "_HighestResultsPage", false);
                return (o == null) ? (Int16)0 : (Int16)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "_HighestResultsPage", false, value);
            }
        }

        protected Int16 _ResultsRequested {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "_ResultsRequested", false);
                return (o == null) ? (Int16)0 : (Int16)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "_ResultsRequested", false, value);
            }
        }

        protected bool m_bIsKeywordQuery {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_bIsKeywordQuery", false);
                return (o == null) ? false : (bool)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_bIsKeywordQuery", false, value);
            }
        }

        protected bool _NeedSpecialTerms {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "_NeedSpecialTerms", false);
                return (o == null) ? false : (bool)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "_NeedSpecialTerms", false, value);
            }
        }

        protected bool _NeedHighConfResults {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "_NeedHighConfResults", false);
                return (o == null) ? false : (bool)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "_NeedHighConfResults", false, value);
            }
        }

        protected bool _SpecialTermInformationAvailable {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "_SpecialTermInformationAvailable", false);
                return (o == null) ? false : (bool)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "_SpecialTermInformationAvailable", false, value);
            }
        }

        protected Exception m_Exception {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_Exception", false);
                return o as Exception;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_Exception", false, value);
            }
        }

        protected PagingCookie PagingCookie {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "PagingCookie", true);
                return o as PagingCookie;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "PagingCookie", true, value);
            }
        }

        protected string _srhoFullTextQuery {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "FullTextQuery", true);
                return o as string;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "FullTextQuery", true, value);
            }
        }

        protected string _srhoKeywordQuery {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "KeywordQuery", true);
                return (o == null) ? string.Empty : (string)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "KeywordQuery", true, value);
            }
        }

        protected bool SaveInfoForQueryLogging {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "SaveInfoForQueryLogging", true);
                return (bool)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "SaveInfoForQueryLogging", true, value);
            }
        }

        protected string m_FullTextQuerySummary {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_FullTextQuerySummary", false);
                return (o as string);
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_FullTextQuerySummary", false, value);
            }
        }

        protected string _QueryLanguage {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "_QueryLanguage", false);
                return (o == null) ? string.Empty : (string)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "_QueryLanguage", false, value);
            }
        }

        protected ResultsView _ResultView {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "_ResultView", false);
                return (o == null) ? ResultsView.Relevance : (ResultsView)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "_ResultView", false, value);
            }
        }

        protected List<string> _ScopesSearched {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "_ScopesSearched", true);
                return (o == null) ? null : (List<string>)o;
            }
        }

        protected string m_strScope {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_strScope", false);
                return (o == null) ? string.Empty : (string)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_strScope", false, value);
            }
        }

        protected string m_strSerializedQuery {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_strSerializedQuery", false);
                return (o == null) ? string.Empty : (string)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_strSerializedQuery", false, value);
            }
        }

        protected ResultTableCollection m_Result {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_Result", false);
                return o as ResultTableCollection;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_Result", false, value);
            }
        }

        protected int m_totalRows {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_totalRows", false);
                return (o == null) ? 0 : (int)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_totalRows", false, value);
            }
        }

        protected int m_RowCount {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_RowCount", false);
                return (o == null) ? 0 : (int)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_RowCount", false, value);
            }
        }

        protected int m_BestBetRowCount {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_BestBetRowCount", false);
                return (o == null) ? 0 : (int)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_BestBetRowCount", false, value);
            }
        }

        protected int m_HighConfidenceRowCount {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_HighConfidenceRowCount", false);
                return (o == null) ? 0 : (int)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_HighConfidenceRowCount", false, value);
            }
        }

        private string m_strContextualScopeUrl {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "m_strContextualScopeUrl", false);
                return (o == null) ? string.Empty : (string)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "m_strContextualScopeUrl", false, value);
            }
        }
        private /* static */ char[] m_split {
            get {
                object o = Reflector.GetFieldOrProperty(get_srhoType(), "m_split", false);
                return (o == null) ? null : (char[])o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(get_srhoType(), "m_split", false, value);
            }
        }
        private bool _enableUrlSmashing {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "_enableUrlSmashing", false);
                return (o == null) ? false : (bool)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "_enableUrlSmashing", false, value);
            }
        }
        public bool NeedCoreResults {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "NeedCoreResults", true);
                return (o == null) ? false : (bool)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "NeedCoreResults", true, value);
            }
        }
        public bool NeedStats {
            get {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "NeedStats", true);
                return (o == null) ? false : (bool)o;
            }
            set {
                object o = Reflector.SetFieldOrProperty(this.SRHO, "NeedStats", true, value);
            }
        }

        #endregion

        /// <summary>
        /// 
        /// </summary>
        /// <param name="queryWherePart">A clause to be added to other clauses as part of the query. Other form and querystring params will still work because it is appended with an AND</param>
        /// <returns></returns>
        public string ComposeFullTextQuery(string queryWherePart) {
            return call_srhoComposeFullTextQuery(queryWherePart) as string;
        }

        private bool _workAroundDoneQuery = false;

        /// <summary>
        /// Provides various ways of getting core results through reflection.
        /// Warning: this is the method actually calls the search web service.
        /// </summary>
        /// <param name="bUseEnhancedCall">If true, Uses our disassembled version of GetResultData instead of the one in srho. If no value is specified the method is determined by the presence of a string in OverrideSqlWriteFieldName.</param>
        public XmlDocument get_CoreResults(bool bUseEnhancedCall) {
            // TODO replace this with a slightly *enhanced* call routine
            if (bUseEnhancedCall) {
                if (!this.m_fDoneQuery || !_workAroundDoneQuery) {
                    this.GetResultData();
                    _workAroundDoneQuery = true;
                }
                Exception e = this.m_Exception;
                if (e != null)
                    throw e;
                return this.m_xmlResponseDoc;
            } else {
                object o = Reflector.GetFieldOrProperty(this.SRHO, "CoreResults", true);
                return o as XmlDocument;
            }
        }

        protected object call_srhoComposeFullTextQuery(string queryWherePart) {
            object o = Reflector.InvokeMember(this.SRHO, "ComposeFullTextQuery", new object[] { queryWherePart });
            return o;
        }

        #region Reflection Management for SRHO object

        private void EnsureSRHO() {
            if (_srho == null) {
                _srho = get_srho(_wp);
                if (_srho == null)
                    throw new NullReferenceException("The calling method must instantiate _srho, but EnsureSRHO() failed to get the instance of the internal srho field.");
            }
        }

        protected Type get_srhoType() {
            EnsureSRHO();
            return _srho.GetType();
        }

        protected object get_srho(CoreResultsWebPart wp) {
            object o = Reflector.GetFieldOrProperty(wp, typeof(CoreResultsWebPart), "srho", false);
            return o;
        }

        #endregion

        private void SetKeywordQueryProperties(Microsoft.Office.Server.Search.Query.Query myRequest) {
            KeywordQuery query = (KeywordQuery)myRequest;
            query.QueryText = this.KeywordQuery;
            StringBuilder builder = new StringBuilder();
            if (!string.IsNullOrEmpty(this.m_strScope)) {
                foreach (string str2 in this.m_strScope.Split(m_split)) {
                    builder.Append(" scope:\"");
                    builder.Append(str2);
                    builder.Append('"');
                }
            }
            if (!string.IsNullOrEmpty(this.m_strContextualScopeUrl)) {
                builder.Append(" site:\"");
                builder.Append(this.m_strContextualScopeUrl);
                builder.Append('"');
            }
            query.HiddenConstraints = builder.ToString();
            query.EnableUrlSmashing = this._enableUrlSmashing;
            if (this.NeedCoreResults || this.NeedStats) {
                if (this._ResultView == ResultsView.Modified_Date) {
                    // BEGIN customization
                    string sortField = (string.IsNullOrEmpty(this.OverrideSqlWriteFieldName))
                                            ? "Write"
                                            : this.OverrideSqlWriteFieldName;
                    query.SortList.Add(sortField, Microsoft.Office.Server.Search.Query.SortDirection.Descending);
                    // END customization
                } else if (this._ResultView == ResultsView.Relevance) {
                    query.SortList.Add("Rank", Microsoft.Office.Server.Search.Query.SortDirection.Descending);
                    query.SortList.Add("WorkId", Microsoft.Office.Server.Search.Query.SortDirection.Descending);
                }
                if (this.SearchRequestProperties.Count > 0) {
                    foreach (string str in this.SearchRequestProperties) {
                        query.SelectProperties.Add(str);
                    }
                }
            }
        }

        // TODO implement this biotch!
        protected virtual void GetResultData() {
            object o = null; // used to store results returns from reflection invoke calls
            Page thisPage = this._wp.Page;// this._wp.Page =(was) this.thisPage
            if (!thisPage.IsCallback && (!this.m_fDoneQuery || !this._workAroundDoneQuery)) {
                if (string.IsNullOrEmpty(this.FullTextQuery)) {
                    this.m_bIsKeywordQuery = true;
                }

                if (this.m_bIsKeywordQuery && string.IsNullOrEmpty(this.KeywordQuery)) {
                    // TODO find this resource somehow and use it, instead of cusing a string constant
                    //WebPartPlatform.Current.GetLocResourceString(LocStringId.SearchResults_NoKeyword)
                    string msg1 = "The were no keywords in your query.";
                    this.m_Exception = NewSrhdcNoKeywordException(msg1, 0);
                    throw this.m_Exception;
                }
                if (this.m_iStartAt > (this._HighestResultsPage * this._ResultsRequested)) {
                    // TODO find this resource somehow and use it, instead of using a string constant
                    //WebPartPlatform.Current.GetLocResourceString(LocStringId.SearchResults_Config)
                    string msg2 = string.Format("Returning {0} results stating at {1}.", this._HighestResultsPage * this._ResultsRequested, this.m_iStartAt);
                    this.m_Exception = NewSrhdcException(msg2, 0);
                    throw this.m_Exception;
                }
                Query myRequest = null;
                try {

                    // set query
                    if (this.m_bIsKeywordQuery) {
                        myRequest = new KeywordQuery(ServerContext.Current);
                        myRequest.PagingCookie = this.PagingCookie;
                        this.SetKeywordQueryProperties(myRequest);
                        //o = Reflector.InvokeMember(this.SRHO, "SetKeywordQueryProperties", new object[] { myRequest }); // srho.SetKeywordQueryProperties(myRequest);
                    } else {
                        myRequest = new FullTextSqlQuery(ServerContext.Current);
                        myRequest.PagingCookie = this.PagingCookie;
                        if (this._ResultView == ResultsView.Modified_Date) {
                            string sortField = (string.IsNullOrEmpty(this.OverrideSqlWriteFieldName))
                                                                        ? "Write"
                                                                        : this.OverrideSqlWriteFieldName;
                            myRequest.QueryText = this.FullTextQuery + string.Format(" Order By {0} desc", sortField);
                        } else if (this._ResultView == ResultsView.Relevance) {
                            myRequest.QueryText = this.FullTextQuery + " Order By Rank desc";
                        }
                        myRequest.KeywordInclusion = KeywordInclusion.AnyKeyword;
                        // TODO implement ULS logging here
                        //ULS.SendTraceTag(ULSTagID.tag_7ht0, ULSCat.msoulscat_SEARCH_Query, ULSTraceLevel.High, "Full Text Query: %s", new object[] { this.FullTextQuery });
                    }

                    // set language
                    try {
                        string qlang = this._QueryLanguage;
                        if (!string.IsNullOrEmpty(qlang)) {
                            myRequest.Culture = new CultureInfo(qlang);
                        } else if ((thisPage.Request.UserLanguages != null) && (thisPage.Request.UserLanguages.Length > 0)) {
                            myRequest.Culture = new CultureInfo(thisPage.Request.UserLanguages[0]);
                        }
                    } catch (Exception exception2) {
                        // TODO implement ULS logging here
                        //ULS.SendTraceTag(ULSTagID.tag_8u79, ULSCat.msoulscat_SEARCH_Query, ULSTraceLevel.Verbose, "Ignoring exception in CultureInfo ctor: %s", new object[] { exception2.ToString() });
                        myRequest.Culture = CultureInfo.CurrentCulture;
                    }
                    o = Reflector.InvokeMember(this.SRHO, "SetQueryProperties", new object[] { myRequest }); // srho.SetQueryProperties(myRequest);

                    if (this.SaveInfoForQueryLogging) {
                        this._ScopesSearched.Add(this.m_strScope);
                    }
                    StringWriter w = new StringWriter();
                    XmlTextWriter xmlWriter = new XmlTextWriter(w);

                    o = Reflector.InvokeMember(myRequest, "SerializeQuery", new object[] { xmlWriter }); // myRequest.SerializeQuery(xmlWriter);

                    this.m_strSerializedQuery = w.ToString();
                    this.m_Result = myRequest.Execute();
                    this.PagingCookie = myRequest.PagingCookie;
                    XmlElement xmlResults = null;

                    using (ResultTable table = this.m_Result[ResultType.RelevantResults]) {
                        this.m_RowCount = table.RowCount;
                        this.m_totalRows = table.TotalRows;
                        this.m_xmlResponseDoc = new XmlDocument();
                        xmlResults = this.m_xmlResponseDoc.CreateElement("All_Results");
                        o = Reflector.InvokeMember(this.SRHO, "AppendHitsToXmlDocument", new object[] { this.m_xmlResponseDoc, xmlResults, table, true }); // this.AppendHitsToXmlDocument(this.m_xmlResponseDoc, xmlResults, table, true);
                    }

                    // high confidence results
                    string definition = null;
                    if (this._NeedSpecialTerms || this._NeedHighConfResults) {
                        this.m_xmlHighConfDoc = new XmlDocument();
                        XmlElement newChild = this.m_xmlHighConfDoc.CreateElement("All_Results");
                        if (this._NeedSpecialTerms) {
                            XmlElement element3 = this.m_xmlHighConfDoc.CreateElement("SpecialTermInformation");
                            XmlElement element7 = this.m_xmlHighConfDoc.CreateElement("Keyword");
                            element7.InnerText = this.m_Result.KeywordInformation.Keyword;
                            element3.AppendChild(element7);
                            XmlElement element6 = this.m_xmlHighConfDoc.CreateElement("Description");
                            definition = this.m_Result.KeywordInformation.Definition;
                            element6.InnerText = definition;
                            element3.AppendChild(element6);
                            newChild.AppendChild(element3);
                            if (!string.IsNullOrEmpty(this.m_Result.KeywordInformation.Keyword) || !string.IsNullOrEmpty(this.m_Result.KeywordInformation.Definition)) {
                                this._SpecialTermInformationAvailable = true;
                            }
                            using (ResultTable table3 = this.m_Result[ResultType.SpecialTermResults]) {
                                this.m_BestBetRowCount = table3.RowCount;
                                XmlElement element5 = this.m_xmlHighConfDoc.CreateElement("BestBetResults");
                                o = Reflector.InvokeMember(this.SRHO, "AppendHitsToXmlDocument", new object[] { this.m_xmlHighConfDoc, element5, table3, false }); // this.AppendHitsToXmlDocument(this.m_xmlResponseDoc, xmlResults, table, true); // this.AppendHitsToXmlDocument(this.m_xmlHighConfDoc, element5, table3, false);
                                newChild.AppendChild(element5);
                            }
                        }
                        if (this._NeedHighConfResults) {
                            using (ResultTable table2 = this.m_Result[ResultType.HighConfidenceResults]) {
                                this.m_HighConfidenceRowCount = table2.RowCount;
                                XmlElement element4 = this.m_xmlHighConfDoc.CreateElement("HighConfidenceResults");
                                o = Reflector.InvokeMember(this.SRHO, "AppendHitsToXmlDocument", new object[] { this.m_xmlHighConfDoc, element4, table2, false });  //this.AppendHitsToXmlDocument(this.m_xmlHighConfDoc, element4, table2, false);
                                newChild.AppendChild(element4);
                            }
                        }
                        this.m_xmlHighConfDoc.AppendChild(newChild);
                    }
                    if ((definition == null) || (definition.Length == 0)) {
                        o = Reflector.InvokeMember(this.SRHO, "GetDiscoveredDefinitions", new object[] { this.m_xmlResponseDoc, xmlResults }); // this.GetDiscoveredDefinitions(this.m_xmlResponseDoc, xmlResults);
                    }
                    this.m_xmlResponseDoc.AppendChild(xmlResults);
                    this.m_fDoneQuery = true;

                } catch (Exception exception) {
                    this.m_fDoneQuery = true;
                    if ((((exception is AllNoiseQueryException) || (exception is SearchServiceNotFoundException)) || ((exception is ScopeNotFoundException) || (exception is TimeoutException))) || ((((exception is QueryContainsOnlyExcludedTermsException) || (exception is InvalidPropertyException)) || ((exception is PluggableAccessCheckException) /*|| (exception is UnSupportedTopologyException)*/)) || ((exception.GetType().Name == "ProductExpiredException") || (exception.GetType().Name == "SrhdcNoInternalUrlException")))) {
                        this.m_Exception = NewSrhdcException(exception.Message, 1);
                    } else {
                        this.m_Exception = NewSrhdcGenericException(exception);
                    }
                    throw this.m_Exception;
                } finally {
                    if (myRequest != null) {
                        myRequest.Dispose();
                    }
                } // try / catch / finally
            } // if / else
        }

        protected Exception NewSrhdcGenericException(Exception exception) {
            string typeName = "Microsoft.Office.Server.Search.WebControls.SrhdcGenericException";
            Type t = this.SRHO.GetType().Assembly.GetType(typeName, true);
            if (t == null)
                throw new Exception(string.Format("Could not get type for {0}.", typeName));
            ConstructorInfo c = t.GetConstructor(new Type[] { typeof(Exception) });
            if (c == null)
                throw new Exception(string.Format("Could not get constructor for {0}.", typeName));
            object o = c.Invoke(new object[] { exception });
            if (o == null)
                throw new Exception(string.Format("Could not invoke constructor for {0}.", typeName));
            return o as Exception;
        }

        protected Exception NewSrhdcException(string message, int number) {
            string typeName = "Microsoft.Office.Server.Search.WebControls.SrhdcException";
            Type t = this.SRHO.GetType().Assembly.GetType(typeName, true);
            if (t == null)
                throw new Exception(string.Format("Could not get type for {0}.", typeName));
            ConstructorInfo c = t.GetConstructor(new Type[] { typeof(string), typeof(int) });
            if (c == null)
                throw new Exception(string.Format("Could not get constructor for {0}.", typeName));
            object o = c.Invoke(new object[] { message, number });
            if (o == null)
                throw new Exception(string.Format("Could not invoke constructor for {0}.", typeName));
            return o as Exception;
        }

        protected Exception NewSrhdcNoKeywordException(string message, int number) {
            string typeName = "Microsoft.Office.Server.Search.WebControls.SrhdcNoKeywordException";
            Type t = this.SRHO.GetType().Assembly.GetType(typeName, true);
            if (t == null)
                throw new Exception(string.Format("Could not get type for {0}.", typeName));
            ConstructorInfo c = t.GetConstructor(new Type[] { typeof(string), typeof(int) });
            if (c == null)
                throw new Exception(string.Format("Could not get constructor for {0}.", typeName));
            object o = c.Invoke(new object[] { message, number });
            if (o == null)
                throw new Exception(string.Format("Could not invoke constructor for {0}.", typeName));
            return o as Exception;
        }

    } // class

} // namespace
